<?php

/**
 *  普通订单支付
 */

namespace app\api\service;

use app\api\model\OrderPayment as ModelOrderPayment;
use app\common\BusinessLog;
use app\common\Calculate;
use app\common\service\Upload;
use app\facade\Basic;
use app\api\model\OrderPayment as OrderPaymentModel;
use coinpal\Payment;
use think\facade\Config;
use app\common\service\CompleteNotificationService;

class OrderPayment
{
    /**
     *  拉起支付
     */
    public function goPay($order, $param)
    {
        /* 无法支付 & 审核 */
        if ($order->status != 10 && $order->status != 21) {
            return $this->noPayment($order);
        }

        switch ($param['payment_method']) {
            case 1:
                return $this->cryptoPay($order);
            case 2:
                return $this->coinbasePay($order);
            case 3:
                return $this->wireTransfer($order, $param);
            default:
                return $this->noPayment($order);
        }
    }


    /**
     * Crypto Pay
     */
    public function cryptoPay($order)
    {
        if ($order->total_amount == 0) {
            return $this->noPayment($order);
        }

        /* 获取支付的商品名称和表述 */
        $request = Request();
        $OrderService = new Order();
        $orderProduct = $OrderService->getProductInfo($order);


        /* 获取支付价格 */
        $payablePrice = $this->getOrderPaymentPrice($order);

        $config = [
            'debug' => true,
            'version' => '2',
            'merchantNo' => Config::get('coinpal.merchantNo'),
            'apiKey' => Config::get('coinpal.apiKey'),
        ];

        $PaymentMethod = new PaymentMethod();
        $PaymentMethodItem = $PaymentMethod->getPaymentMethodItem(1);

        $payment = new Payment();

        //回调链接
        $env = env('APP_ENV') ?? 'prod';
        $url = Config::get('domain')[$env]['erpapi'];
        $mallUrl = Config::get('domain')[$env]['mall'];

        try {
            $payment = $payment->setMerchantNo($config['merchantNo'])->setVersion($config['version'])->setApiKey($config['apiKey']);
            $data['requestId'] = 'Q' . date('YmdHis') . uniqid();
            $data['orderNo'] = $order->order_no;
            $data['orderCurrencyType'] = 'fiat';
            $data['orderCurrency'] = 'USD';
            $data['orderDescription'] =  $orderProduct['description'];
            $data['orderAmount'] =  $payablePrice;
            $data['notifyURL'] = $url . '/api/coinpal/notify';
            $data['redirectURL'] = $mallUrl . "/order/confirm";
            $data['payerIP'] = $request->ip();
            $data['remark'] = 'order';

            $result = $payment->create($data);

            if (empty($result)) {
                return Basic::data(1, 'payment.paymentFailed');
            }

            if ($result['respCode'] !== 200) {
                return Basic::data(1, 'payment.paymentFailed');
            }

            $pay_data['order_id'] = $order->id;
            $pay_data['payment_method'] = $PaymentMethodItem['id'];
            $pay_data['payment_method_name'] = $PaymentMethodItem['name'];
            $pay_data['pay_type'] = '00';
            $pay_data['pay_amount'] = $payablePrice;
            $pay_data['create_time'] = date("Y-m-d H:i:s", time());
            $pay_data['status'] = '03';
            $pay_data['order_type'] = $order->order_category;
            $pay_data['order_no'] = $order->order_no;
            $pay_data['user_id'] = $order->user_id;
            $pay_data['pay_code'] = $result['requestId'];
            $pay_data['pay_currency'] = $order->currency;
            $pay_data['payment_url'] = $result['nextStepContent'];

            $result = OrderPaymentModel::create($pay_data);
            if (!$result) {
                return Basic::data(1, 'payment.paymentFailed');
            }

            $data = [];
            $data['order_type'] = $order->order_category;
            $data['order_no'] = $order->order_no;
            $data['payment_url'] = $pay_data['payment_url'];
            return Basic::data(0, 'common.success', $data);
        } catch (\coinpal\PaymentException $e) {

            $payment->log($e);
            return Basic::data(1, 'payment.paymentFailed');
        }
    }

    /**
     * Coinbase Pay
     */
    public function coinbasePay($order)
    {

        /* 查询支付记录 */
        $where['order_id'] = $order->id;
        $where['order_type'] = $order->order_category;
        $where['status'] = '00';
        $OrderPayment = OrderPaymentModel::where($where)->find();

        /* 采购 */
        if ($order->order_category == 'wholesal') {
            $DistributorOrder = new DistributorOrder();
            $item = $DistributorOrder->getProductInfo($order);
            if (!$OrderPayment) {

                ApiClient::init(Config::get('coinbase.apiKey'));

                $chargeData = [
                    'name' => $item['name'],
                    'description' => $item['description'],
                    'local_price' => [
                        'amount' => $order->order_amount,
                        'currency' => 'USD'
                    ],
                    'pricing_type' => 'fixed_price',
                    'requested_info' => [$order->order_no, $order->id]
                ];

                // $chargeObj = Charge::create($chargeData);


                $ins_data['order_type'] = $order->order_category;
                $ins_data['order_id'] = $order->id;
                $ins_data['order_no'] = $order->order_no;
                $ins_data['payment_method'] = $order->payment_method;
                $ins_data['payment_method_name'] = $order->payment_method_name;
                $ins_data['pay_type'] = '00';
                $ins_data['pay_amount'] = $order->order_amount;
                $ins_data['create_time'] = date("Y-m-d H:i:s", time());
                $ins_data['status'] = '00';

                $reslut = OrderPaymentModel::create($ins_data);

                if (!$reslut) {
                    return Basic::data(1, 'payment.paymentFailed');
                }

                $data = [];
                $data['order_type'] = $order->order_category;
                $data['order_no'] = $order->order_no;
                $data['payment_method'] = $order->payment_method;
                $data['payment_method_name'] = $order->payment_method_name;
                $data['payment_url'] = 'https://commerce.coinbase.com/charges/123456';
                return Basic::data(0, 'order.createOrderSuccess', $data);
            }
            /* 普通订单 */
            if ($order->order_category == 'order') {
                $data = [];
                $data['order_type'] = $order->order_category;
                $data['order_no'] = $order->order_no;
                $data['payment_method'] = $order->payment_method;
                $data['payment_method_name'] = $order->payment_method_name;
                $data['payment_url'] = 'https://commerce.coinbase.com/charges/123456';
                return Basic::data(0, 'order.createOrderSuccess', $data);
            }
        } else {

            $data = [];
            $data['order_type'] = $order->order_category;
            $data['order_no'] = $order->order_no;
            $data['payment_method'] = $order->payment_method;
            $data['payment_method_name'] = $order->payment_method_name;
            $data['payment_url'] = 'https://commerce.coinbase.com/charges/123456';
            return Basic::data(0, 'order.createOrderSuccess', $data);
        }
    }


    /**
     *  银行转账
     */
    public function wireTransfer($order, $param)
    {
        if (empty($order)) {
            return Basic::data(1, 'order.orderNotExist');
        }

        //order_payment
        $pay_where = [];
        $pay_where['order_id'] = $order->id;
        $pay_where['payment_method'] = 3;
        $pay_where['order_type'] = $order->order_category;
        $pay_count =  ModelOrderPayment::where($pay_where)->count();

        /* 首次可以跳过支付 */
        if (!$pay_count && !isset($param['file'])) {

            $data = [];
            $pay_where['order_type'] = $order->order_category;
            $data['order_no'] = $order->order_no;
            $data['payment_method'] = $order->payment_method;
            $data['payment_method_name'] = $order->payment_method_name;
            $data['payment_url'] = '##';

            return Basic::data(0, 'order.voucherUploadSuccess', $data);
        }

        if (empty($param['file'])) {
            return Basic::data(1, 'order.voucherNotExist');
        }

        if ($pay_count >= 9) {
            return Basic::data(1, 'order.paymentWouchersCannotExceed9Items');
        }

        /* 判断最新条 */
        $OrderPaymentItem = ModelOrderPayment::where($pay_where)->order('id DESC')->find();

        if ($OrderPaymentItem) {
            if ((time() - strtotime($OrderPaymentItem->create_time))  < 20) {
                return Basic::data(1, 'order.tooFrequentOperation');
            }
        }

        /* 上传图片 */
        $Upload = new Upload();
        $result = $Upload->uploadImages($param['file'], 6);
        if ($result['code'] !== 0) {
            return Basic::data(1, 'order.voucherUploadFailed');
        }

        $order_transfer = [];
        $order_transfer['order_id'] = $order->id;
        $PaymentMethod = new PaymentMethod();
        $PaymentMethod = $PaymentMethod->getPaymentMethodItem(3);
        $order_transfer['payment_method'] = $PaymentMethod['id'];
        $order_transfer['payment_method_name'] = $PaymentMethod['name'];


        $order_transfer['voucher_code'] = $param['voucher_code'];
        $order_transfer['paid_amount'] = $param['paid_amount'];
        $order_transfer['pay_currency'] = $order->currency;
        $order_transfer['pay_time'] = date("Y-m-d H:i:s", time());
        $order_transfer['pay_amount'] = Calculate::pricecalc($order->total_amount, '-', $order->pay_amount, 2);
        $order_transfer['pay_type'] = '00';
        $order_transfer['create_time'] = date("Y-m-d H:i:s", time());
        $order_transfer['status'] = '00';
        $order_transfer['order_type'] = $order->order_category;
        $order_transfer['order_id'] = $order->id;
        $order_transfer['order_no'] = $order->order_no;
        $order_transfer['user_id'] = $param['user_id'];

        /* 自支付凭证 */
        $order_transfer['notes'] = $param['voucher_remark'];
        $order_transfer['transfer_voucher_id'] = $result['data']['id'];

        $result = ModelOrderPayment::create($order_transfer);

        $notificationService = new CompleteNotificationService();
        $notificationService->send('order_upload_payment_voucher', $order->toArray());
        /* 写入普通订单取消日志 */
        $Business = new BusinessLog();
        $Business->logOperation( $result->id, 'orderPayment', '待审核', '支付凭证上传待审核',2);


        if ($result) {
            return Basic::data(0, 'common.success');
        } else {
            return Basic::data(1, 'common.error');
        }
    }


    /**
     *  沒有支付方式
     */
    public function noPayment($order)
    {
        $data = [];
        $data['order_type'] = $order->order_category;;
        $data['order_no'] = $order->order_no;
        $data['no_payment'] = 1;
        $data['payment_method'] = 3;
        $data['payment_method_name'] = 'No Payment Method';
        $data['payment_url'] = '#';
        return Basic::data(0, 'order.createOrderSuccess', $data);
    }


    /**
     *  上传支付凭证
     */



    /**
     *  订单多次支付，获取订单待支付价格
     */
    public function getOrderPaymentPrice($order)
    {

        $payablePrice = 0;

        $where = ['order_id' => $order->id, 'status' => '01'];
        $result = ModelOrderPayment::where($where)->field('id,paid_amount,status')->select()->toArray();

        if ($result) {
            $paid_amount = 0;
            foreach ($result as $value) {
                $paid_amount = Calculate::pricecalc($paid_amount, '+', $value['paid_amount'], 2);
            }
            $payablePrice = Calculate::pricecalc($order->total_amount, '-', $paid_amount, 2);
        } else {
            if ($order->pay_terms == 1) {
                $payablePrice = $order->advance_amount;
            } else {
                $payablePrice = $order->total_amount;
            }
        }
        return $payablePrice;
    }
}
